/*
    * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
 */

#include "share_manager.h"
#include "file_share_client.h"

namespace OHOS {
namespace FileShare {
ShareManager &ShareManager::GetInstance()
{
    static ShareManager instance;
    return instance;
}

int32_t ShareManager::SendFile(SendTask &task)
{
    if (task.deviceId.empty() || task.files.empty()) {
        LOGE("SendFile failed, deviceId or fileInfo is empty.");
        return FS_INVALID_PARAM;
    }

    int32_t ret = CheckShareType(task.type);
    if (ret != FS_SUCCESS) {
        LOGE("SendFile failed, check share type failed, type: %{public}d.", (int) task.type);
        return ret;
    }

    if (task.type == ShareType::SAVE_AS_FOLDER && task.folderName.empty()) {
        LOGE("SendFile failed, folder name is empty.");
        return FS_INVALID_PARAM;
    }

    ret = FileShareClient::GetInstance().SendFile(task);
    if (ret != FS_SUCCESS) {
        LOGE("SendFile failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}

int32_t ShareManager::RegisterFileShareCallback(const std::string &bundleName, const std::shared_ptr<SendFileCallback> &callback)
{
    if (bundleName.empty()) {
        LOGE("RegisterFileShareCallback failed, bundleName is empty.");
        return FS_INVALID_PARAM;
    }
    CHKPTR(callback, FS_NULL_PARAM);

    sptr<FileShareCallback> fileShareCallback = new (std::nothrow) FileShareCallback();
    if (fileShareCallback == nullptr) {
        LOGE("RegisterFileShareCallback failed, out of memory.");
    }
    fileShareCallback->SetSendFileCallback(callback);
    sendFileCallbackMap_[bundleName][CallbackType::FILE_SHARE] = fileShareCallback;

    int32_t ret = FileShareClient::GetInstance().RegisterFileShareCallback(fileShareCallback);
    if (ret != FS_SUCCESS) {
        LOGE("RegisterFileShareCallback failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}

int32_t ShareManager::UnRegisterFileShareCallback(const std::string &bundleName)
{
    if (bundleName.empty()) {
        LOGE("RegisterFileShareCallback failed, bundleName is empty.");
        return FS_INVALID_PARAM;
    }

    if (sendFileCallbackMap_.find(bundleName) == sendFileCallbackMap_.end()) {
        LOGE("UnRegisterFileShareCallback failed, bundleName : %{public}s not found.", bundleName.c_str());
        return FS_INVALID_PARAM;
    } else if (sendFileCallbackMap_[bundleName].find(CallbackType::FILE_SHARE) == sendFileCallbackMap_[bundleName].end()) {
        LOGE("UnRegisterFileShareCallback failed, CallbackType : %{public}d not found.", (int32_t)CallbackType::FILE_SHARE);
        return FS_INVALID_PARAM;
    }

    sendFileCallbackMap_[bundleName].erase(CallbackType::FILE_SHARE);

    int32_t ret = FileShareClient::GetInstance().UnRegisterFileShareCallback();
    if (ret != FS_SUCCESS) {
        LOGE("UnRegisterFileShareCallback failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}

int32_t ShareManager::CancelSendFile(const std::string &deviceId, SendType type)
{
    if (deviceId.empty()) {
        LOGE("CancelSendFile failed, deviceId is empty");
        return FS_INVALID_PARAM;
    }

    int32_t ret = FileShareClient::GetInstance().CancelSendFile(deviceId, type);
    if (ret != FS_SUCCESS) {
        LOGE("CancelSendFile failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}

int32_t ShareManager::SetShareStatus(const bool status)
{
    int32_t ret = FileShareClient::GetInstance().SetShareStatus(status);
    if (ret != FS_SUCCESS) {
        LOGE("SetShareStatus failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}

int32_t ShareManager::GetShareStatus(bool &status)
{
    int32_t ret = FileShareClient::GetInstance().GetShareStatus(status);
    if (ret != FS_SUCCESS) {
        LOGE("GetShareStatus failed, ret: %{public}d", ret);
        return ret;
    }
    
    return FS_SUCCESS;
}

std::string ShareManager::GetStoragePath()
{
    return FileShareClient::GetInstance().GetStoragePath();
}

int32_t ShareManager::SetStoragePath(std::string &path)
{
    return FileShareClient::GetInstance().SetStoragePath(path);
}

int32_t ShareManager::GetWorkDuration()
{
    return FileShareClient::GetInstance().GetWorkDuration();
}

int32_t ShareManager::SetWorkDuration(int32_t &time)
{
    return FileShareClient::GetInstance().SetWorkDuration(time);
}

int32_t ShareManager::CheckShareType(ShareType type)
{
    switch (type) {
        case ShareType::SAVE_AS_FILE:
        case ShareType::SAVE_AS_FOLDER:
        case ShareType::SAVE_TO_MEDIA_ASSET:
            return FS_SUCCESS;
        default:
            return FS_INVALID_PARAM;
    }
}

int32_t ShareManager::RegisterShareStatusCallback(const std::string &bundleName, const std::shared_ptr<ShareStatusCallback> &callback)
{
    if (bundleName.empty()) {
        LOGE("RegisterFileShareCallback failed, bundleName is empty.");
        return FS_INVALID_PARAM;
    }
    CHKPTR(callback, FS_NULL_PARAM);

    sptr<FileShareCallback> fileShareCallback = new (std::nothrow) FileShareCallback();
    if (fileShareCallback == nullptr) {
        LOGE("RegisterFileShareCallback failed, out of memory.");
    }
    fileShareCallback->SetShareStatusCallback(callback);
    sendFileCallbackMap_[bundleName][CallbackType::SHARE_STATUS] = fileShareCallback;

    int32_t ret = FileShareClient::GetInstance().RegisterShareStatusCallback(bundleName, fileShareCallback);
    if (ret != FS_SUCCESS) {
        LOGE("RegisterFileShareCallback failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}
int32_t ShareManager::UnRegisterShareStatusCallback(const std::string &bundleName)
{
    if (bundleName.empty()) {
        LOGE("RegisterFileShareCallback failed, bundleName is empty.");
        return FS_INVALID_PARAM;
    }

    if (sendFileCallbackMap_.find(bundleName) == sendFileCallbackMap_.end()) {
        LOGE("UnRegisterFileShareCallback failed, bundleName : %{public}s not found.", bundleName.c_str());
        return FS_INVALID_PARAM;
    } else if (sendFileCallbackMap_[bundleName].find(CallbackType::SHARE_STATUS) == sendFileCallbackMap_[bundleName].end()) {
        LOGE("UnRegisterFileShareCallback failed, CallbackType : %{public}d not found.", (int32_t)CallbackType::SHARE_STATUS);
        return FS_INVALID_PARAM;
    }

    sendFileCallbackMap_[bundleName].erase(CallbackType::SHARE_STATUS);

    int32_t ret = FileShareClient::GetInstance().UnRegisterShareStatusCallback(bundleName);
    if (ret != FS_SUCCESS) {
        LOGE("UnRegisterFileShareCallback failed, ret: %{public}d", ret);
        return ret;
    }

    return FS_SUCCESS;
}

int32_t ShareManager::ChangeUuid(const uint16_t uuid)
{
    if (uuid == 0) {
        LOGE("ChangeUuid failed, uuid is 0.");
        return FS_INVALID_PARAM;
    }
    
    return FileShareClient::GetInstance().ChangeUuid(uuid);
}
} // namespace FileShare
} // namespace OHOS